using StackExchange.Redis;

namespace Crux.Core.Cache.Extensions;
/// <summary>
/// LockInfo
/// </summary>
public class LockInfo
{
    /// <summary>
    ///
    /// </summary>
    public Guid Id { get; set; } = Guid.NewGuid();
    /// <summary>
    ///
    /// </summary>
    public DateTime LockTime { get; set; } = DateTime.Now;
    /// <summary>
    /// 
    /// </summary>
    public RedisValue LockValue => $"{LockTime:yyyy-MM-dd HH:mm:ss.fff}";
    /// <summary>
    ///
    /// </summary>
    public TimeSpan Expiry { get; set; } = TimeSpan.FromSeconds(10);
    private CancellationTokenSource _source { get; init; } = new CancellationTokenSource();
    private List<CancellationTokenRegistration> _registrations { get; init; } = new List<CancellationTokenRegistration>();
    /// <summary>
    /// 是否自动失效了
    /// </summary>
    public bool IsAutoExpiry()
    {
        var expired = DateTime.Now >= LockTime.Add(Expiry);

        try
        {
            return expired;
        }
        finally
        {
            if (expired &&
                !_source.IsCancellationRequested)
            {
                Cancel();
            }
        }
    }
    /// <inheritdoc/>
    public void Cancel()
    {
        foreach (var registration in _registrations)
        {
            using var _ = registration;
        }

        if (!_source.IsCancellationRequested)
        {
            _source.Cancel();
        }
    }

    /// <inheritdoc/>
    public static LockInfo CreateState()
    {
        return new LockInfo();
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="task"></param>
    public void Register(Action task)
    {
        var registration = _source.Token.Register(task);

        _registrations.Add(registration);
    }
}